{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<!--BOOK_INFORMATION-->\n",
    "<img align=\"left\" style=\"padding-right:10px;\" src=\"figures/PHydro-cover-small.png\">\n",
    "*This is the Jupyter notebook version of the [Python in Hydrology](http://www.greenteapress.com/pythonhydro/pythonhydro.html) by Sat Kumar Tomer.*\n",
    "*Source code is available at [code.google.com](https://code.google.com/archive/p/python-in-hydrology/source).*\n",
    "\n",
    "*The book is available under the [GNU Free Documentation License](http://www.gnu.org/copyleft/fdl.html). If you have comments, corrections or suggestions, please send email to satkumartomer@gmail.com.*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<!--NAVIGATION-->\n",
    "< [Indexing](03.03-Indexing.ipynb) | [Contents](Index.ipynb) | [4. Basic Applications in Hydrology](04.00-Basic-Applications-in-Hydrology.ipynb) >"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.4 数组操作\n",
    "\n",
    "我们经常需要改变数组，转置它，获取一些元素，或者改变一些元素。这个例子说明了这一点，其中我们首先创建数组，然后再使用它。我们在上一节已经看到，我们可以通过调用索引来改变元素的值，然后为它赋新的值。首先，我们生成正态分布随机数的大小为(2x5)创建一个我们想要操作的数组。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.53326884, -0.92598299, -2.16101108],\n",
       "       [-1.18508159, -0.5418438 ,  0.04271229]])"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "foo = np.random.randn(2,3)\n",
    "foo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个数组使用T属性进行转置。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.53326884, -1.18508159],\n",
       "       [-0.92598299, -0.5418438 ],\n",
       "       [-2.16101108,  0.04271229]])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo.T"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们可以访问数组中的某些元素，如果需要的话，也可以为它们赋值新的值。在这个例子中，我们首先访问(0,1)索引处的元素，然后我们用5代替它。最终，我们将打印变量来检查变量是否被修改。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-0.92598298529893075"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo[0,1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.53326884,  5.        , -2.16101108],\n",
       "       [-1.18508159, -0.5418438 ,  0.04271229]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo[0,1]=5\n",
    "foo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "任意数组的形状都是通过使用`reshape`方法来改变的。在reshape操作过程中，元素数量的变化是不允许的。在下面的例子中，首先我们将创建一个大小为(3×6)的数组，并且将其形状改变为(2×9)。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "foo = np.random.randn(3,6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.42476917, -0.64989266,  0.34298771, -0.1273063 ,  1.99715616,\n",
       "        -1.7297553 ,  0.19860873, -0.59915169,  0.88832268],\n",
       "       [-0.7813623 ,  1.84357458,  0.51911179, -0.15162753, -0.80676   ,\n",
       "        -0.15564674, -0.02632338,  0.07629451,  1.10469739]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo.reshape(2,9)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "就像我们可以访问数组中的任意元素并改变它一样，我们可以访问任意属性并修改它们。然而，只有在属性是可写时，才允许修改，新值对变量有一定意义。我们可以使用这种行为，并使用形状属性来改变变量的形状。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4, 3)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo = np.random.randn(4,3)\n",
    "foo.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.19201064, -0.81341485,  0.92661679],\n",
       "       [-0.31279339, -1.30641514, -0.30636886],\n",
       "       [-1.69554358,  1.21494097,  0.99583744],\n",
       "       [-0.86650171,  0.86610918, -1.22166541]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2, 6)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo.shape = 2,6\n",
    "foo.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.19201064, -0.81341485,  0.92661679, -0.31279339, -1.30641514,\n",
       "        -0.30636886],\n",
       "       [-1.69554358,  1.21494097,  0.99583744, -0.86650171,  0.86610918,\n",
       "        -1.22166541]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在上面的例子中，首先定义一个大小为(4×3)的数组，然后给它的形状赋值(2,6)，这个使得数组的大小为(2×6)。因为我们不能够改变元素的数量，所以如果我们定义新变量的第一维度，第二维度可以轻松计算。Numpy允许我们在这种情况下为默认维度定义`-1`。我们也可以通过使用默认维度在变量的形状上做出所需的改变。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2, 6)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo.shape = -1,6\n",
    "foo.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们可以通过使用`ravel`坦化数组(使数组成为一维)，这在以下示例中进行了解释:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.14396677,  0.5547482 ,  0.61119573],\n",
       "       [ 0.32195338,  0.38274366,  0.97030368]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo = np.random.rand(2,3)\n",
    "foo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2, 3)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "foo.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = foo.ravel()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(6,)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.14396677,  0.5547482 ,  0.61119573,  0.32195338,  0.38274366,\n",
       "        0.97030368])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
